#include <iostream>
#include <functional>
#include <string>
#include <memory>
#include <cassert>
#include <map>
using namespace std;

class Function{
protected:
    string context;
    static map<string, function<shared_ptr<Function>(string)>> classes_map;
public:
    // 注册函数，添加到map
    static void Register(string class_name, function<shared_ptr<Function>(string)> create_function){
        cout << "insert " << class_name << " to map." << endl;
        classes_map[class_name] = create_function;
    }

    // 创建函数，通过class_map找到静态创建函数的地址，然后调用函数，返回函数的返回值。
    static shared_ptr<Function> Create(string class_name, string params){
        for(map<string, function<shared_ptr<Function>(string)>>::iterator it = classes_map.begin(); it != classes_map.end(); it++){
            if(it->first == class_name){
                // 调用创建函数并返回返回值。
                return (it->second)(params);
            }
        }
        cout << "cnnot found object by name." << endl;
        assert(false);
    }
};

map<string, function<shared_ptr<Function>(string)>> Function::classes_map;

class Resize : public Function{
private:
    static struct Resize_Register{
        Resize_Register(){
            registe();
        }
    } resize_register;
public:
    Resize(string params){
        context = params;
        cout << "Resize create: " << context << endl;
    }

    ~Resize(){
        cout << "Resize destroy: " << context << endl;
    }

    static void registe(){
        Function::Register("resize", createObject);
    }

    static shared_ptr<Function> createObject(string params){
        return make_shared<Resize>(params);
    }
};

struct Resize::Resize_Register Resize::resize_register;

class Crop : public Function{
private:
    static struct Crop_Register{
        Crop_Register(){
            registe();
        }
    } crop_register;
public:
    Crop(string params){
        context = params;
        cout << "Crop create: " << context << endl;
    }

    ~Crop(){
        cout << "Crop destroy: " << context << endl;
    }

    static void registe(){
        Function::Register("crop", createObject);
    }

    static shared_ptr<Function> createObject(string params){
        return make_shared<Crop>(params);
    }
};

struct Crop::Crop_Register Crop::crop_register;

int main(){
    cout << "init." << endl;
    shared_ptr<Function> f0 = Function::Create("resize", "function 0");
    shared_ptr<Function> f1 = Function::Create("crop", "function 1");
    cout << "end." << endl;
    return 0;
}